package com.store.utils;

import com.store.controller.lt.LoginController;
import com.store.entity.Resource;
import com.store.entity.User;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

@Component
public class RequestUtils {

    //private static Logger logger = LoggerFactory.getLogger(RequestUtils.class);

    /**
     * 	获取当前登录的用户，若用户未登录，则返回未登录 json
     * @return
     */
    public static User currentLoginUser() {
        Subject subject = SecurityUtils.getSubject();
        if (subject.isAuthenticated()) {
            Object principal = subject.getPrincipals().getPrimaryPrincipal();
            if (principal instanceof User) {
                return (User) principal;
            }
        }
        return null;
    }

    /**
     * 根据是否打包成jar，来获取类的信息
     * @param packageName 控制器所在的包路径
     * @return 控制器下所有.class文件
     */
    public List<String> getAllClass (String packageName) throws IOException {
        List<String> classNames = new ArrayList<>();
        String path = this.getClass().getResource("/").getPath();
        path = URLDecoder.decode(path, "UTF-8");
        if (path.lastIndexOf(".jar") != -1) {
            //如果是jar包，路径会有所不同
            path = path.substring(path.indexOf("file:/")+6, path.lastIndexOf(".jar")+4);
            //System.out.println("path="+path);
            //读取压缩文件
            ZipInputStream zip = new ZipInputStream(new FileInputStream(path));
            for (ZipEntry entry = zip.getNextEntry();entry != null; entry = zip.getNextEntry()) {
                //com\zking\web
                if (entry.getName().contains("Controller") && !entry.isDirectory()
                        && entry.getName().endsWith(".class")) {
                    String className = entry.getName();
                    classNames.add(className.substring(className.lastIndexOf("/")+1));
                }
            }
        } else {
            //不是jar环境，正常路径
            path += packageName;
            classNames= Arrays.asList(new File(path).list());
        }
        return classNames;
    }

    /**
     * 获取控制层下所有的访问路径
     * @return
     */
    public List<Resource> getResources() throws ClassNotFoundException, IOException {
        //获取本类的对象
        Class clas = LoginController.class;
        //获取包路径
        String packageName = clas.getPackage().getName().replaceAll("\\.","/");
        //获取类所在的绝对根路径
        String path = clas.getResource("/").getPath();
        path = URLDecoder.decode(path, "UTF-8");
//        String filePath = path + packageName;
//        System.out.println("filePath="+filePath);
        //根据是否打包jar来查询路径
        RequestUtils requestUtils = new RequestUtils();
        List<String> classNames = getAllClass(packageName);
        //找到该类下的所有类文件
//        File file = new File(filePath);
//        File[] files = file.listFiles();

        List<Resource> resources = new ArrayList<>();
        for (String className : classNames) {
            //获取类名
            className = className.substring(0, className.lastIndexOf(".class"));
            //去掉内部类的情况
            if (className.indexOf("$") != -1) {
                //去掉内部类
                //className = className.substring(0, className.indexOf("$"));
                continue;
            }

            //获取类的反射
            Class clas2 = Class.forName(clas.getPackage().getName()+"."+className);
            //获取每个类的RequestMapping注解
            RequestMapping requestMapping = (RequestMapping) clas2.getAnnotation(RequestMapping.class);
            if (requestMapping == null) continue;//没有RequestMapping，直接跳过
            //设置得到的跟目录
            Resource sr1 = new Resource();
            sr1.setResname(requestMapping.name());
            String controllerUrl = requestMapping.value()[0];
            //判断是不是以/开头
            controllerUrl = controllerUrl.startsWith("/")?controllerUrl:"/"+controllerUrl;
            sr1.setResurl(controllerUrl);
            //将这个资源加入到集合
            resources.add(sr1);
            //获取所有方法的请求
            Method[] methods = clas2.getDeclaredMethods();
            for (Method method : methods) {
                RequestMapping requestMapping2 = method.getAnnotation(RequestMapping.class);
                if (requestMapping2 != null) {
                    Resource sr2 = new Resource();
                    sr2.setResname(requestMapping2.name());
                    String methodUrl = requestMapping2.value()[0];
                    //判断是不是以/开头
                    methodUrl = methodUrl.startsWith("/")?methodUrl:"/"+methodUrl;
                    sr2.setResurl(sr1.getResurl()+methodUrl);
                    resources.add(sr2);
                }
            }
        }
        return resources;
    }


}
